package net.gdface.sdk;

import java.util.Arrays;
import java.util.Comparator;

import net.gdface.utils.BufferUtils;
import net.gdface.utils.BinaryUtils;

/**
 * FSE搜索结果对象<br>
 * 该类实现了{@link Comparable}接口，可以根据相似度结果字段({@link FseResult#similarity})排序
 * @author guyadong
 *
 */
public  class FseResult implements Comparable<FseResult>{	
	/**
	 * 特征码ID,
	 * 特征码的MD5校验值(使用MD5保证特征码ID的唯一性)
	 */
	private	byte[] featureId=null;
	/**
	 * 用于识别特征拥有者的Id
	 * 由应用应用层解释
	 */
	private String owner=null;
	/**
	 * 相似度比较结果，代表当前特征码与输入搜索人脸特征的相似度比较值。
	 */
	private double similarity=0;
	
	public FseResult() {
	}
	public FseResult(byte[] featureId, String owner, double similarity) {
		this.featureId = featureId;
		this.owner = owner;
		this.similarity = similarity;
	}
	
	@Override
	public int compareTo(FseResult o) {
		double sub = similarity - o.similarity;
		return sub > 0 ? 1 : (sub < 0 ? -1 : 0);
	}

	/**
	 * 将{@link #owner}转为应用id(Long),如果{@link #owner}为{@code null}则返回{@code null}
	 * @return
	 */
	public Long appLongId(){
		return asAppID(owner);
	}
	/**
	 * 将{@link #owner}转为应用id(Integer),如果{@link #owner}为{@code null}则返回{@code null}
	 * @return
	 */
	public Integer appIntId(){
		Long l = asAppID(owner);
		return l == null ? null : l.intValue();
	}
	/**
	 * 用于相似度排序的{@link Comparator}实例
	 */
	public static final Comparator<FseResult> COMPARATOR = new Comparator<FseResult>() {
		@Override
		public int compare(FseResult o1, FseResult o2) {
			return o1.compareTo(o2);
		}
	};
	/**
	 * 从{@link #owner}字段返回Long类型整数,
	 * @param owner HEX格式(32字节长)的MD5
	 * @return owner为{@code null}则返回{@code null}
	 */
	public static Long asAppID(String owner){
		if(owner != null && owner.getBytes().length == 32){			
			return BufferUtils.asLongArray(BinaryUtils.hex2Bytes(owner))[1];
		}
		return null;
	}
	public byte[] getFeatureId() {
		return featureId;
	}
	public void setFeatureId(byte[] featureId) {
		this.featureId = featureId;
	}

	public String getOwner() {
		return owner;
	}
	public void setOwner(String owner) {
		this.owner = owner;
	}
	public double getSimilarity() {
		return similarity;
	}
	public void setSimilarity(double similarity) {
		this.similarity = similarity;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + Arrays.hashCode(featureId);
		result = prime * result + ((owner == null) ? 0 : owner.hashCode());
		return result;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof FseResult))
			return false;
		FseResult other = (FseResult) obj;
		if (!Arrays.equals(featureId, other.featureId))
			return false;
		if (owner == null) {
			if (other.owner != null)
				return false;
		} else if (!owner.equals(other.owner))
			return false;
		return true;
	}
	@Override
	public String toString() {
		String out=String.format("featureId=[%s],imgMD5=[%s],similarity=%f", BinaryUtils.toHex(featureId),owner,similarity);		
		return out;
	}
}